        TITL DAI FIRMWARE 1E22B-1E413  V1.0  Rev.1
        ORG   :E22B
*
*
*
********************
* INTEGER DIVISION *
********************
*
* Signed 32-bit fixed point division:
*       MACC = MACC / MEM.
*
* Entry: HL: Points to divisor.
* Exit:  All registers preserved.
*
XIDIV   PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        CALL  :E242     Signed division
        CALL  :E3CF     Quotient into MACC
        JMP   :C14D     Popall, ret
*
************************
* INT DIVIDE REMAINDER *
************************
*
* For INT values: MACC = Remainder of (MACC / MEM).
*
* Entry: HL: Points to divisor.
* Exit:  All registers preserved.
*
XIREM   PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        CALL  :E242     Signed division;
 REM Remainder in MACC
        JMP   :C14D     Popall, ret
*
***************************
* SIGNED INTEGER DIVISION *
***************************
*
* Divides MACC / MEM; quotient is left in registers
* B,C,D,E and the remainder in MACC.
*
* Entry: HL:     Points to divisor.
*        MACC:   Dividend.
* Exit:  BCDE:   Quotient; remainder in MACC.
*        S-flag: Set for result.
*        AHL:    Corrupted, CY=0.
*
L1E24   CALL  :ED8F     Get signbyte dividend in A,
 REM compare it with sign divisor
        MOV   A,B       Get signbyte dividend
        PUSH  PSW       Save result compare
        CALL  :EA0E     Copy divisor into BCDE
        MOV   A,B       )
        ORA   C         ) Check if divisor = 0
        ORA   D         )
        ORA   E         )
        JZ    :E2E4     Then error 'divide by zero'
        MOV   A,B       Get signbyte divisor
        ORA   A         Is it negative ?
        CM    :E3C9     Then negate divisor
        JC    :E2E4     Error exit if overflow
        PUSH  B         ) Save divisor on stack
        PUSH  D         )
        CALL  :E2EC     Normalize divisor
        CMA             ) H = pos. value of nr of
        INR   A         ) times shifted for norma-
        MOV   H,A       ) lisation
        LDA   :00D5     Get signbyte dividend
        ORA   A         Is dividend negative ?
        CM    :E315     Then change sign dividend
        CALL  :E3D6     Copy dividend in reg BCDE
        ORA   C         )
        ORA   D         ) Check if dividend zero
        ORA   E         )
        JZ    :E2E0     Then abort, leaving 0000 in
 REM MACC and reg BCDE
        CALL  :E2EC     Normalize dividend; nrs of
 REM shifts in A
        POP   D         ) Restore divisor in BCDE
        POP   B         )
        ADD   H         Add nr of shifts for divisor
 REM H is total nrs of shifts
        JM    :E2C9     If resulting nrs of shifts
 REM < 0 then result = 0000
        CALL  :EB39     Shift divisor left (A) times
        PUSH  D         ) Save shifted divisor on
        PUSH  B         ) stack
        LXI   B,:8000   Init BCDE for max neg number
        LXI   D,:0000
        CALL  :EB55     Shift BCDE right (A) times
        MOV   H,B       ) Shifted BC in HL
        MOV   L,C       )
        POP   B         Get hibytes shifted divisor
        XTHL            HL: lobytes shifted divisor;
 REM shifted BC on stack
        XCHG            DE: lobytes shifted divisor;
 REM HL: shifted DE
        PUSH  H         Shifted DE on stack
L1E25   LHLD  :00D7     Get lobytes dividend
        MOV   A,H       )
        SUB   E         )
        MOV   H,A       ) (00D7/8)=(00D7/8)-lobytes
        MOV   A,L       ) shifted divisor
        SBB   D         )
        MOV   L,A       )
        SHLD  :00D7     )
        LHLD  :00D5     Get hibytes dividend
        MOV   A,H       )
        SBB   C         )
        MOV   H,A       ) (00D5/6)=(00D5/6)-hibytes
        MOV   A,L       ) shifted divisor
        SBB   B         )
        MOV   L,A       )
        SHLD  :00D5     )
L1E26   POP   H         Get shifted DE
        RAL
        CMC
        MOV   A,L
        RAL
        MOV   L,A
        MOV   A,H
        RAL
        MOV   H,A
        XTHL            Get shifted 'BC' in HL
        MOV   A,L
        RAL
        MOV   L,A
        MOV   A,H
        RAL
        MOV   H,A
        XTHL            New 'BC' back on stack
        JC    :E2D0
        CALL  :EB70     Rotate BCDE right 1 bit
        MOV   A,L
        RAR
        PUSH  H         New 'DE' back on stack
        JC    :E28E     CY=1: again
        CALL  :E2F2     MACC = MACC + BCDE
        JMP   :E2A6     Again
 REM
* If resulting nr of shifts is negative:
 REM
L1E27   LXI   D,:0000
        PUSH  D
        JMP   :E2D7     BCDE = 0000; abort
 REM
* If ready:
 REM
L1E28   MOV   A,L
        RAR
        PUSH  H
        CNC   :E2F2     CY=0: MACC = MACC + BCDE
        POP   D
L1E29   POP   B
        POP   PSW       Get result sign compare
        CALL  :ED88     Evt negate BCDE
        CM    :E315     Evt change sign MACC
        RET
 REM
* If dividend is zero:
 REM
L1E30   POP   H         ) Save BCDE = 0000
        POP   H         )
        POP   PSW
        RET
 REM
* If errors:
 REM
L1E31   CC    :C04B     CY=1: Run overflow error
        CZ    :C06C     Z=1: Run divide by 0 error
        POP   PSW
        RET
*
*********************************************
* INT: NORMALIZE CONTENTS REGISTERS B,C,D,E *
*********************************************
*
* Exit: HL preserved.
*
L1E32   PUSH  H
        CALL  :EBA0     Normalize BCDE (INT)
        POP   H
        RET
*
******************************************
* ADD CONTENTS REGISTERS B,C,D,E TO MACC *
******************************************
*
* Exit: BCDE preserved, AHL corrupted.
*       F set on hibyte of result.
*
L1E33   LHLD  :00D7     )
        MOV   A,H       )
        ADD   E         ) Add DE to 00D7/8
        MOV   H,A       )
        MOV   A,L       )
        ADC   D         )
        MOV   L,A
        SHLD  :00D7
        LHLD  :00D5
        MOV   A,H       )
        ADC   C         )
        MOV   H,A       ) Add BC to 00D5/6
        MOV   A,L       )
        ADC   B         )
        MOV   L,A       )
        SHLD  :00D5
        RET
*
***********
* INT ABS *
***********
*
* For INT values: MACC = absolute value of MACC.
*
* Exit: All registers preserved.
*
XIABS   PUSH  PSW
        LDA   :00D5     Get sign byte
        ORA   A
        CM    :E315     If <0: change sign
        POP   PSW
        RET
*
**********************************
* INT: CHANGE SIGN MACC CONTENTS *
**********************************
*
* For INT values: MACC = - MACC.
*
* Exit: All registers preserved.
*
XICHS   PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        CALL  :E3D6     Copy MACC into reg BCDE
        CALL  :E3C9     Negate BCDE
        JNC   :E328     Jump if no error
 REM
* If overflow error:
 REM
L1E36   CALL  :C04B     Run overflow error
        JMP   :C14D     Popall, ret
 REM
* If O.K.:
 REM
L1E37   CALL  :E3CF     Copy reg BCDE into MACC
        JMP   :C14D     Popall, ret
*
********
* IAND *
********
*
* Logical 'AND': MACC = MACC IAND MEM.
*
* Entry: HL points to operand in memory.
* Exit:  All registers preserved.
*
XIAND   PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        JMP   :ECE1     Prepare IAND and perform
*
****************
* PERFORM IAND *
****************
*
* Performs: MEM IAND EBCA, result in ABCD.
*
* Entry: HL points to last byte of MEM.
*        Fixed point number in EBCA.
* Exit:  HL points to 1st byte of MEM.
*        E preserved.
*
SIAND   ANA   M
        MOV   D,A
        DCX   H
        MOV   A,C
        ANA   M
        MOV   C,A
        DCX   H
        MOV   A,B
        ANA   M
        MOV   B,A
        DCX   H
        MOV   A,E
        ANA   M
        RET
*
L1E40   DBL   :E385     (not used)
*
*******
* IOR *
*******
*
* Logical 'OR': MACC = MACC IOR MEM.
*
* Entry: HL points to operand in memory.
* Exit:  All registers preserved.
*
XIOR    PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        JMP   :ECEA     Prepare IOR and perform
*
***************
* PERFORM IOR *
***************
*
* Performs MEM IOR EBCA. Result in ABCD.
*
* Entry: HL points to last byte of MEM.
*        Fixed point nr in EBCA.
* Exit:  HL points to 1st byte of MEM.
*        E preserved.
*
SIOR    ORA   M
        MOV   D,A
        DCX   H
        MOV   A,C
        ORA   M
        MOV   C,A
        DCX   H
        MOV   A,B
        ORA   M
        MOV   B,A
        DCX   H
        MOV   A,E
        ORA   M
        RET
*
L1E43   DBL   :E385     (not used)
*
********
* IXOR *
********
*
* Logical 'XOR': MACC = MACC IXOR MEM.
*
* Entry: HL points to operand in memory.
* Exit:  All registers preserved.
*
XIXOR   PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        JMP   :ECF3     Prepare IXOR and perform
*
****************
* PERFORM IXOR *
****************
*
* Performs MEM IXOR EBCA, result in ABCD.
*
* Entry: HL points last byte of MEM.
*        Fixed point number in EBCA.
* Exit:  HL points to 1st byte of MEM.
*        E preserved.
*
SIXOR   XRA   M
        MOV   D,A
        DCX   H
        MOV   A,C
        XRA   M
        MOV   C,A
        DCX   H
        MOV   A,B
        XRA   M
        MOV   B,A
        DCX   H
        MOV   A,E
        XRA   M
        RET
*
L1E46   DBL   :E385     (not used)
*
********
* INOT *
********
*
* Logical 'INOT': MACC = INOT (MACC).
*
* Exit: All registers preserved.
*
XINOT   PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        CALL  :ECFC     Copy MACC into ABCD; CMA
        MOV   E,A       Save hibyte
        MOV   A,D
        CMA             INOT D
        MOV   D,A
        MOV   A,C
        CMA             INOT C
        MOV   C,A
        MOV   A,B
        CMA             INOT B
        MOV   B,A
L1E48   MOV   A,E       Get back hibyte
L1E49   CALL  :E126     Copy ABCD into MACC
        JMP   :C14D     Popall, ret
*
L1E50   RET             (not used)
*
***********************************
* COPY MACC INTO REG. E,B,C,A     *
* D = compl. 00D5 EXOR hibyte MEM *
***********************************
*
* Entry: HL points to 1st byte MEM.
* Exit:  HL points to last byte MEM.
*        D = complement EXOR hibytes MACC and MEM.
*            Msb D = 1: sign bits identical.
*            Msb D = 0: sign bits different.
*
L1E51   JMP   :ED01     Copy MACC into ABCD, A in E;
 REM jump to E38F
*
L1E52   XRA   M         EXOR sign bytes
        CMA             Complement result
        INX   H
        INX   H
        INX   H
        PUSH  D
        MOV   D,A       A = compl EXOR signbytes
        POP   PSW       Get D in A
        RET
*
*******
* SHR *
*******
*
* MACC = MACC SHR MEM.
* Shifts contents MACC right (MEM) places.
*
* Entry: HL points to operand in memory.
* Exit:  All registers preserved.
*        Result is 0 if MEM < 0 or > 31.
*
XSHR    PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        CALL  :ED08     Check MEM. If <=31:
 REM MACC into BCDE, shift in A
 REM Else: clear ABCDE
        CALL  :EB55     Shift BCDE right A places
        JMP   :E328     BCDE into MACC; quit
*
*******
* SHL *
*******
*
* MACC = MACC SHL MEM.
* Shifts contents MACC left (MEM) places.
*
* Entry/exit: See XSHR.
*
XSHL    PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        CALL  :ED08     Check MEM. If <= 31: MACC
 REM into BCDE, shift in A
 REM Else: clear ABCDE
        CALL  :EB39     Shift BCDE left A places
        JMP   :E328     BCDE into MACC; quit
*
*******************************
* TEST VALUE OF AN INT NUMBER *
*******************************
*
* Tests if an INT has a value between 0 and 31.
* If true: Number into A, else: Clear ABCDE.
*
* Entry: HL points to a 4-byte number.
* Exit:  Nr <= #1F: Number in A.
*        Nr > #1F: ABCDE cleared.
*        HL points to 4th byte in memory.
*
XSTST   MOV   A,M       Get 1st byte
        INX   H
        ORA   M         OR with 2nd
        INX   H
        ORA   M         OR with 3rd
        INX   H
        JNZ   :E3C2     Jump if highest bytes <>0
        MOV   A,M       Get 4th byte
        ANI   :E0       Test 3 highest bits
        NOP
        NOP
        MOV   A,M       Get 4th byte in A
        RZ              Abort if 4th byte <= #1F
 REM
* If nr > #1F:
 REM
L1E56   MVI   A,:00     )
        MOV   B,A       )
        MOV   C,A       ) Clear ABCDE
        MOV   D,A       )
        MOV   E,A       )
        RET
*
******************************************
* INT: NEGATE CONTENTS REGISTERS B,C,D,E *
******************************************
*
* Exit: HL preserved.
*       CY=1: Overflow into msb.
*
L1E57   PUSH  H
        CALL  :EB82     Negate BCDE (INT)
        POP   H
        RET
*
************************************
* COPY REGISTERS B,C,D,E INTO MACC *
************************************
*
* Entry: none.
* Exit:  ABCD corrupted, FHL preserved.
*
L1E58   MOV   A,B
        MOV   B,C
        MOV   C,D
        MOV   D,E
        JMP   :E126     Copy ABCD into MACC
*
************************************
* COPY MACC INTO REGISTERS B,C,D,E *
************************************
*
* Entry: None.
* Exit:  AFHL preserved.
*
L1E59   PUSH  PSW
        CALL  :E133     Copy MACC into ABCD
        JMP   :ED13     Copy ABCD into BCDE
*
L1E60   RET
*
*******************************
* CHANGE CONTENTS MACC TO FPT *
*******************************
*
* Result is incorrect if MACC = 80 00 00 00.
* Then exponent is 1 too high (E3FC should be
* a NOP instruction).
*
* Entry: None.
* Exit:  All registers preserved.
*
XFLT    PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        CALL  :E3D6     Copy MACC into BCDE
        CALL  :ED83     Check if BCDE is 0.
        JZ    :E40E     Then clear MACC + BCDE
        MVI   H,:20     Init exp.byte for pos.nr
        MOV   A,B       )
        ORA   A         ) Check sign bit
        JP    :E3FD     Jump if nr is positive
 REM
* If INT nr is negative:
 REM
        MVI   H,:A0     Init exp.byte for neg.nr
        CALL  :E3C9     Negate BCDE
        JNC   :E3FD     Jump if no overflow
        MVI   B,:80
        INR   H
 REM
* Convert to FPT:
 REM
L1E62   MOV   A,H       Get init.exp.byte
        LXI   H,:00D5   Addr MACC
        MOV   M,A       Init.exp.byte in MACC
        PUSH  H
        CALL  :EB96     Normalize BCDE
        POP   H
        MOV   A,M       Get init.exp.byte
        CALL  :E9DB     Copy ABCD into MACC
        JMP   :C14D     Popall, ret
 REM
* If INT number is 0:
 REM
L1E63   CALL  :EA16     Clear MACC + reg ABCD
        JMP   :C14D     Popall; ret
*
*
*
        END
